package com.gitee.ixtf.lucene.kotlinx

import com.gitee.ixtf.core.IEntity
import com.gitee.ixtf.core.IEntityLoggable
import com.gitee.ixtf.core.IOperator
import com.gitee.ixtf.core.kotlinx.date
import com.gitee.ixtf.lucene.Jlucene.CREATE_DATE_TIME
import com.gitee.ixtf.lucene.Jlucene.CREATOR
import com.gitee.ixtf.lucene.Jlucene.MODIFIER
import com.gitee.ixtf.lucene.Jlucene.MODIFY_DATE_TIME
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*
import org.apache.lucene.document.*
import org.apache.lucene.document.Field.Store
import org.apache.lucene.document.Field.Store.NO

fun Document.text(field: String, v: String?, store: Store = NO) {
  v?.takeIf { it.isNotBlank() }?.also { add(TextField(field, it, store)) }
}

fun Document.keyword(field: String, v: String?, store: Store = NO) {
  v?.takeIf { it.isNotBlank() }?.also { add(KeywordField(field, it, store)) }
}

fun Document.enum(field: String, e: Enum<*>?, store: Store = NO) = keyword(field, e?.name, store)

fun Document.entity(field: String, v: IEntity?, store: Store = NO) = keyword(field, v?.id, store)

fun Document.entity(field: String, v: IOperator?, store: Store = NO) = keyword(field, v?.id, store)

fun Document.loggable(v: IEntityLoggable?) {
  entity(CREATOR, v?.creator)
  date(CREATE_DATE_TIME, v?.createDateTime)
  entity(MODIFIER, v?.modifier)
  date(MODIFY_DATE_TIME, v?.modifyDateTime)
}

fun Document.date(field: String, v: Date?) {
  v?.apply {
    add(LongPoint(field, time))
    add(NumericDocValuesField(field, time))
  }
}

fun Document.date(field: String, v: LocalDate?) = date(field, v?.date())

fun Document.date(field: String, v: LocalDateTime?) = date(field, v?.date())

fun Document.boolean(field: String, b: Boolean) = int(field, if (b) 1 else 0)

fun Document.int(field: String, i: Int?) {
  i?.also { add(IntPoint(field, it)) }
}

fun Document.long(field: String, l: Long?) {
  l?.also { add(LongPoint(field, it)) }
}

fun Document.double(field: String, d: Double?) {
  d?.also { add(DoublePoint(field, it)) }
}

fun Document.string(field: String, v: String?, store: Store = NO) {
  v?.takeIf { it.isNotBlank() }?.also { add(StringField(field, it, store)) }
}
